package com.codenjoy.calculator;

/**
 * Created by User on 31.01.2015.
 */
public class BaseParcer implements Parser {
    public static final String ABCDEFG = "0123456789ABCDEFG";
    int base;

    public BaseParcer(String base) {
        this.base = checkBase(base);
    }

    @Override
    public long decode(String inp) {
        return baseToDec(base, inp);
    }

    @Override
    public String encode(long result) {
        return format(base, result);
    }

    private long baseToDec(int base, String strToConvert) {
        long sum = 0;
        for (int i = 0; i < strToConvert.length() ; i++) {
            char c = strToConvert.substring(i, i + 1).charAt(0);
            sum = base*sum + ABCDEFG.indexOf(c);
        }
        return sum;
    }

    private String format(int base, long sum) {
        String res = "";
        long l = sum;
        do {
            int h = (int)(l % base);
            l = l / base;
            res = ABCDEFG.charAt(h) + res;
        } while (l >= 1);
        return res;
    }

    public void validate(String expr) {
        boolean b = false;
        int pos = 0;
        for (int i = 0; i < expr.length(); i++) {
            if (expr.charAt(i) == '+') {
                pos = i;
                continue;
            }

            char d = expr.charAt(i);
            int in = ABCDEFG.indexOf(d);
            b |= (in < 0) || in >= base;
        }

        if (pos == 0 || pos == expr.length() || expr.split("[+]").length != 2) {
            throw new IllegalArgumentException("Invalid expression format");
        }

        if (b) {
            throw new IllegalArgumentException("Invalid number");
        }

    }

    private int checkBase(String bs) {
        int base;
        try {
            base = Integer.valueOf(bs);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("Invalid base", e);
        }
        if (base > ABCDEFG.length() || base <= 1) {
            throw new IllegalArgumentException("Invalid base");
        }
        return base;
    }

}
